/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
  						       dialog_caravan_creation.h

	$Header: $

	$NoKeywords: $

 ************************************************************************/

#ifndef DIALOG_CARAVAN_CREATION_H_INCLUDED
#define DIALOG_CARAVAN_CREATION_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <deque>
#include <list>
#include <map>
#include <vector>

#include "adv_dwelling.h"
#include "adv_dwelling_ptr.h"
#include "adv_object_list_image.h"
#include "adventure_path_finder.h"
#include "army_ptr.h"
#include "bitmap_layer_window_ptr.h"
#include "bitmap_group_ptr.h"
#include "buffer_window_ptr.h"
#include "button_ptr.h"
#include "caravan_ptr.h"
#include "creature_array.h"
#include "creature_array_window_ptr.h"
#include "creature_icon_window_ptr.h"
#include "game_window.h"
#include "micro_map_window_ptr.h"
#include "pathfinding_subject_ptr.h"
#include "scrollbar_ptr.h"
#include "shared_ptr.h"
#include "text_window_ptr.h"
#include "town.h"
#include "town_ptr.h"

class t_adventure_map;
class t_adventure_object;
class t_bitmap_layer;
class t_micro_map_renderer;
struct t_screen_rect;
class t_town_window;

// ---------------------------------------------------------------------------
// Dialog to create caravans & send them on their way
// ---------------------------------------------------------------------------
class t_dialog_caravan_creation : public t_window
{
	public:
		t_dialog_caravan_creation( t_adventure_map      * map,
								   t_town_window		* parent,
								   t_town				* town );

		bool init_dialog ();

	private:
		enum { k_displayed_locations = 4 }; // Number of locations visible at one time

		// The type of location we are displaying
		enum t_location_type
		{
			k_location_type_origin = 0,
			k_location_type_destination,

			k_location_type_count
		};

		enum t_pathfind_result
		{
			k_pathfind_success = 0,
			k_pathfind_blocked,      // blocked by enemy
			k_pathfind_inaccessable, // blocked by shroud or terrain

			k_pathfind_result_count
		};

		// Note: t_adventure_path_finder's are uncopyable, so use pointers
		typedef std::deque< t_shared_ptr< t_adventure_path_finder > > t_path_finder_array;


		// Holds everything we need to display an origin or destination
		struct t_visible_location
		{
			int						index; // Index in m_locations[ m_location_type ]
			t_button_ptr			button;
			t_text_window_ptr		name_window;
			t_bitmap_window_ptr		name_background;
			t_bitmap_window_ptr		highlight_frame;
			t_bitmap_window_ptr		normal_frame;
			t_buffer_window_ptr		picture;
			t_micro_map_window_ptr	map;
		};

		// A pointer to an origin or destination. Other locations can be dwellings or towns, but nothing else
		struct t_location_ptr
		{
			// Convenience constructors
			t_location_ptr( t_town * town );
			t_location_ptr( t_town_ptr town );
			t_location_ptr( t_adv_dwelling * dwelling );
			t_location_ptr( t_adv_dwelling_ptr dwelling );

			// Turn into t_adventure_object
			operator t_adventure_object*();
			t_adventure_object *operator->();

			union
			{
				t_town * town;
				t_adv_dwelling * dwelling;
			} object;

			bool is_town;
		};

		typedef std::vector< t_location_ptr > t_location_vector;

		// Message handlers
		void buy_clicked( t_button * );
		void cancel_clicked( t_button * );
		void caravan_creature_array_changed();
		void from_town_clicked( t_button * );
		void location_clicked( t_button *, int index );
		void move_caravan_clicked( t_button * );
		void move_garrison_to_caravan_clicked( t_button * );
		void move_single_to_caravan_clicked( t_button * );
		void move_visiting_to_caravan_clicked( t_button * );
		void ok_clicked( t_button * );
		void scroll( t_scrollbar *, int position );
		void send_clicked( t_button * );
		void split_clicked( t_button * );
		void to_town_clicked( t_button * );

		// Misc functions
		void cancel_split_mode();
		t_pathfind_result get_travel_time_from_origin( int origin_index, int &days );
		t_pathfind_result get_travel_time_to_destination( int destination_index, int &days );
		bool remerge_caravan();
		void send_caravan( t_caravan_ptr caravan );
		void send_current_caravan();
		void set_location_type( t_location_type new_type );
		void set_selection( int index );
		bool setup_pathfinder( t_adventure_object *object, t_adventure_path_finder & path_finder );
		bool unselect();
		void update_location( int index );
		void update_text_and_creators();

		t_bitmap_group_ptr						m_bitmaps;
		t_button_ptr							m_buy_button;
		t_creature_icon_window_ptr				m_buy_portrait;
		t_bitmap_window_ptr						m_buy_text_background;
		t_text_window_ptr						m_buy_text_window;
		t_creature_array						m_caravan_army;
		t_bitmap_window_ptr						m_caravan_rings;
		t_text_window_ptr						m_caravan_title;
		t_bitmap_window_ptr						m_caravan_title_background;
		t_creature_array_window_ptr				m_caravan_window;
		t_bitmap_window_ptr						m_double_rings;
		t_button_ptr							m_double_split_button;
		t_button_ptr							m_from_town_button;
		t_text_window_ptr						m_garrison_title;
		t_bitmap_window_ptr						m_garrison_title_background;
		t_creature_array_window_ptr				m_garrison_window;
		t_adv_object_list_image					m_image_creator;
		t_location_type							m_location_type;
		t_location_vector						m_locations[ k_location_type_count ];
		t_adventure_map *						m_map;
		t_button_ptr							m_move_caravan_button;
		t_button_ptr							m_move_garrison_to_caravan_button;
		t_button_ptr							m_move_single_to_caravan_button;
		t_button_ptr							m_move_visiting_to_caravan_button;
		t_button_ptr							m_ok_button;
		t_bool_array							m_origin_permenantly_blocked; // Did the origin pathfinders initialize correctly?
		t_path_finder_array						m_origin_path_finders; // 1 per origin, set up to do caravan pathfinding
	    t_town_window *							m_parent_town_window;
		t_pathfinding_subject_list				m_pathfinding_armies; // Temporary creature arrays, used only for pathfinding
		t_scrollbar_ptr							m_scrollbar;
		int										m_selected_location[ k_location_type_count ];
		t_bitmap_window_ptr						m_single_rings;
		t_button_ptr							m_single_split_button;
		t_creature_array_window_ptr				m_single_window;
		t_army_ptr								m_temp_army;
		t_bitmap_window_ptr						m_text_background;
		t_text_window_ptr						m_text_window;
		t_button_ptr							m_to_town_button;
		t_town *								m_town;
		bool									m_town_permenantly_blocked;
		t_adventure_path_finder					m_town_pathfinder;
		t_button_ptr							m_transport_button;
		t_visible_location						m_visible_locations[ k_displayed_locations ];
		t_army_ptr								m_visiting_army;
		t_creature_array_window_ptr				m_visiting_window;
};

inline t_dialog_caravan_creation::t_location_ptr::t_location_ptr( t_town * town ) 
{
	object.town = town;
	is_town = true;
}

inline t_dialog_caravan_creation::t_location_ptr::t_location_ptr( t_town_ptr town ) 
{
	object.town = town.get();
	is_town = true;
}

inline t_dialog_caravan_creation::t_location_ptr::t_location_ptr( t_adv_dwelling * dwelling ) 
{
	object.dwelling = dwelling;
	is_town = false;
}

inline t_dialog_caravan_creation::t_location_ptr::t_location_ptr( t_adv_dwelling_ptr dwelling ) 
{
	object.dwelling = dwelling.get();
	is_town = false;
}


#endif // DIALOG_CARAVAN_CREATION_H_INCLUDED
